//**********************************************************************
//	Programmer	-	Sujal Bista
//	File Name	-	Graphics.h
//	Description	:	
//					Virtual class that lets us switch between various
//					API's like DX11 or openGL
//**********************************************************************

#ifndef _GRAPHICS_BASE_H_
#define _GRAPHICS_BASE_H_ 

#include "global.h"

namespace graphicsDefinitions
{
	//different types of buffer..copied from http://msdn.microsoft.com/en-us/library/ff476085(v=VS.85).aspx
	enum BIND_FLAG
	{
		BIND_FLAG_VERTEX_BUFFER      = 0x1L,
		BIND_FLAG_INDEX_BUFFER       = 0x2L,
		BIND_FLAG_CONSTANT_BUFFER    = 0x4L,
		BIND_FLAG_SHADER_RESOURCE    = 0x8L,
		BIND_FLAG_STREAM_OUTPUT      = 0x10L,
		BIND_FLAG_RENDER_TARGET      = 0x20L,
		BIND_FLAG_DEPTH_STENCIL      = 0x40L,
		BIND_FLAG_UNORDERED_ACCESS   = 0x80L 
	};
	//different usage of buffer..copied from http://msdn.microsoft.com/en-us/library/ff476259(v=VS.85).aspx
	enum USAGE
	{
		USAGE_DEFAULT     = 0,	//read write by gpu
		USAGE_IMMUTABLE   = 1,	//read only by gpu, cpu no access
		USAGE_DYNAMIC     = 2,	//read only by gpu, write only by cpu
		USAGE_STAGING     = 3	//data transfer from gpu to cpu
	};
	//cpu access for each buffer..copied from http://msdn.microsoft.com/en-us/library/ff476106(v=VS.85).aspx
	enum CPU_ACCESS_FLAG
	{
		CPU_ACCESS_FLAG_NONE    = 0x0L,
		CPU_ACCESS_FLAG_WRITE   = 0x10000L,
		CPU_ACCESS_FLAG_READ    = 0x20000L 
	};


	//type of resource..copied from http://msdn.microsoft.com/en-us/library/ff476202(v=VS.85).aspx
	enum RESOURCE_DIMENSION 
	{
		RESOURCE_DIMENSION_UNKNOWN     = 0,
		RESOURCE_DIMENSION_BUFFER      = 1,
		RESOURCE_DIMENSION_TEXTURE1D   = 2,
		RESOURCE_DIMENSION_TEXTURE2D   = 3,
		RESOURCE_DIMENSION_TEXTURE3D   = 4 
	};


	//misc flag used for creating resources..copied from http://msdn.microsoft.com/en-us/library/ff476203(v=VS.85).aspx
	enum RESOURCE_MISC_FLAG 
	{
		RESOURCE_MISC_FLAG_NONE					  = 0x0L,
		RESOURCE_MISC_FLAG_GENERATE_MIPS            = 0x1L,
		RESOURCE_MISC_FLAG_SHARED                   = 0x2L,
		RESOURCE_MISC_FLAG_TEXTURECUBE              = 0x4L,
		RESOURCE_MISC_FLAG_DRAWINDIRECT_ARGS        = 0x10L,
		RESOURCE_MISC_FLAG_BUFFER_ALLOW_RAW_VIEWS   = 0x20L,
		RESOURCE_MISC_FLAG_BUFFER_STRUCTURED        = 0x40L,
		RESOURCE_MISC_FLAG_RESOURCE_CLAMP           = 0x80L,
		RESOURCE_MISC_FLAG_SHARED_KEYEDMUTEX        = 0x100L,
		RESOURCE_MISC_FLAG_GDI_COMPATIBLE           = 0x200L 
	};
	//different shader types
	enum SHADER_TYPE
	{
		SHADER_TYPE_VERTEX,
		SHADER_TYPE_HULL,
		SHADER_TYPE_DOMAIN,
		SHADER_TYPE_GEOMETRY,
		SHADER_TYPE_PIXEL,
		SHADER_TYPE_COMPUTE,
		SHADER_TYPE_END
	};
	//different types of data fed into vertex shader
	enum INPUT_DATA_TYPE
	{
		INPUT_DATA_TYPE_BINORMAL,
		INPUT_DATA_TYPE_BLENDINDICES,
		INPUT_DATA_TYPE_BLENDWEIGHT,
		INPUT_DATA_TYPE_COLOR,
		INPUT_DATA_TYPE_NORMAL,
		INPUT_DATA_TYPE_POSITION,
		INPUT_DATA_TYPE_POSITIONT,
		INPUT_DATA_TYPE_PSIZE,
		INPUT_DATA_TYPE_TANGENT,
		INPUT_DATA_TYPE_TEXCOORD
	};
	//type of data contained in input slot..this has been copied from http://msdn.microsoft.com/en-us/library/bb205315(v=VS.85).aspx
	enum INPUT_CLASSIFICATION
	{
		INPUT_CLASSIFICATION_PER_VERTEX_DATA=0,
		INPUT_CLASSIFICATION_PER_INSTANCE_DATA =1
	};
	//specifies the format of the input..this has been copied from http://msdn.microsoft.com/en-us/library/bb173059(VS.85).aspx
	enum DATA_FORMAT
	{
			DATA_FORMAT_UNKNOWN                      = 0,
			DATA_FORMAT_R32G32B32A32_TYPELESS        = 1,
			DATA_FORMAT_R32G32B32A32_FLOAT           = 2,
			DATA_FORMAT_R32G32B32A32_UINT            = 3,
			DATA_FORMAT_R32G32B32A32_SINT            = 4,
			DATA_FORMAT_R32G32B32_TYPELESS           = 5,
			DATA_FORMAT_R32G32B32_FLOAT              = 6,
			DATA_FORMAT_R32G32B32_UINT               = 7,
			DATA_FORMAT_R32G32B32_SINT               = 8,
			DATA_FORMAT_R16G16B16A16_TYPELESS        = 9,
			DATA_FORMAT_R16G16B16A16_FLOAT           = 10,
			DATA_FORMAT_R16G16B16A16_UNORM           = 11,
			DATA_FORMAT_R16G16B16A16_UINT            = 12,
			DATA_FORMAT_R16G16B16A16_SNORM           = 13,
			DATA_FORMAT_R16G16B16A16_SINT            = 14,
			DATA_FORMAT_R32G32_TYPELESS              = 15,
			DATA_FORMAT_R32G32_FLOAT                 = 16,
			DATA_FORMAT_R32G32_UINT                  = 17,
			DATA_FORMAT_R32G32_SINT                  = 18,
			DATA_FORMAT_R32G8X24_TYPELESS            = 19,
			DATA_FORMAT_D32_FLOAT_S8X24_UINT         = 20,
			DATA_FORMAT_R32_FLOAT_X8X24_TYPELESS     = 21,
			DATA_FORMAT_X32_TYPELESS_G8X24_UINT      = 22,
			DATA_FORMAT_R10G10B10A2_TYPELESS         = 23,
			DATA_FORMAT_R10G10B10A2_UNORM            = 24,
			DATA_FORMAT_R10G10B10A2_UINT             = 25,
			DATA_FORMAT_R11G11B10_FLOAT              = 26,
			DATA_FORMAT_R8G8B8A8_TYPELESS            = 27,
			DATA_FORMAT_R8G8B8A8_UNORM               = 28,
			DATA_FORMAT_R8G8B8A8_UNORM_SRGB          = 29,
			DATA_FORMAT_R8G8B8A8_UINT                = 30,
			DATA_FORMAT_R8G8B8A8_SNORM               = 31,
			DATA_FORMAT_R8G8B8A8_SINT                = 32,
			DATA_FORMAT_R16G16_TYPELESS              = 33,
			DATA_FORMAT_R16G16_FLOAT                 = 34,
			DATA_FORMAT_R16G16_UNORM                 = 35,
			DATA_FORMAT_R16G16_UINT                  = 36,
			DATA_FORMAT_R16G16_SNORM                 = 37,
			DATA_FORMAT_R16G16_SINT                  = 38,
			DATA_FORMAT_R32_TYPELESS                 = 39,
			DATA_FORMAT_D32_FLOAT                    = 40,
			DATA_FORMAT_R32_FLOAT                    = 41,
			DATA_FORMAT_R32_UINT                     = 42,
			DATA_FORMAT_R32_SINT                     = 43,
			DATA_FORMAT_R24G8_TYPELESS               = 44,
			DATA_FORMAT_D24_UNORM_S8_UINT            = 45,
			DATA_FORMAT_R24_UNORM_X8_TYPELESS        = 46,
			DATA_FORMAT_X24_TYPELESS_G8_UINT         = 47,
			DATA_FORMAT_R8G8_TYPELESS                = 48,
			DATA_FORMAT_R8G8_UNORM                   = 49,
			DATA_FORMAT_R8G8_UINT                    = 50,
			DATA_FORMAT_R8G8_SNORM                   = 51,
			DATA_FORMAT_R8G8_SINT                    = 52,
			DATA_FORMAT_R16_TYPELESS                 = 53,
			DATA_FORMAT_R16_FLOAT                    = 54,
			DATA_FORMAT_D16_UNORM                    = 55,
			DATA_FORMAT_R16_UNORM                    = 56,
			DATA_FORMAT_R16_UINT                     = 57,
			DATA_FORMAT_R16_SNORM                    = 58,
			DATA_FORMAT_R16_SINT                     = 59,
			DATA_FORMAT_R8_TYPELESS                  = 60,
			DATA_FORMAT_R8_UNORM                     = 61,
			DATA_FORMAT_R8_UINT                      = 62,
			DATA_FORMAT_R8_SNORM                     = 63,
			DATA_FORMAT_R8_SINT                      = 64,
			DATA_FORMAT_A8_UNORM                     = 65,
			DATA_FORMAT_R1_UNORM                     = 66,
			DATA_FORMAT_R9G9B9E5_SHAREDEXP           = 67,
			DATA_FORMAT_R8G8_B8G8_UNORM              = 68,
			DATA_FORMAT_G8R8_G8B8_UNORM              = 69,
			DATA_FORMAT_BC1_TYPELESS                 = 70,
			DATA_FORMAT_BC1_UNORM                    = 71,
			DATA_FORMAT_BC1_UNORM_SRGB               = 72,
			DATA_FORMAT_BC2_TYPELESS                 = 73,
			DATA_FORMAT_BC2_UNORM                    = 74,
			DATA_FORMAT_BC2_UNORM_SRGB               = 75,
			DATA_FORMAT_BC3_TYPELESS                 = 76,
			DATA_FORMAT_BC3_UNORM                    = 77,
			DATA_FORMAT_BC3_UNORM_SRGB               = 78,
			DATA_FORMAT_BC4_TYPELESS                 = 79,
			DATA_FORMAT_BC4_UNORM                    = 80,
			DATA_FORMAT_BC4_SNORM                    = 81,
			DATA_FORMAT_BC5_TYPELESS                 = 82,
			DATA_FORMAT_BC5_UNORM                    = 83,
			DATA_FORMAT_BC5_SNORM                    = 84,
			DATA_FORMAT_B5G6R5_UNORM                 = 85,
			DATA_FORMAT_B5G5R5A1_UNORM               = 86,
			DATA_FORMAT_B8G8R8A8_UNORM               = 87,
			DATA_FORMAT_B8G8R8X8_UNORM               = 88,
			DATA_FORMAT_R10G10B10_XR_BIAS_A2_UNORM   = 89,
			DATA_FORMAT_B8G8R8A8_TYPELESS            = 90,
			DATA_FORMAT_B8G8R8A8_UNORM_SRGB          = 91,
			DATA_FORMAT_B8G8R8X8_TYPELESS            = 92,
			DATA_FORMAT_B8G8R8X8_UNORM_SRGB          = 93,
			DATA_FORMAT_BC6H_TYPELESS                = 94,
			DATA_FORMAT_BC6H_UF16                    = 95,
			DATA_FORMAT_BC6H_SF16                    = 96,
			DATA_FORMAT_BC7_TYPELESS                 = 97,
			DATA_FORMAT_BC7_UNORM                    = 98,
			DATA_FORMAT_BC7_UNORM_SRGB               = 99,
			DATA_FORMAT_FORCE_UINT                   = 0xffffffffUL
	};
	//defines the type of primitive..copied from http://msdn.microsoft.com/en-us/library/ff476189(v=VS.85).aspx
	enum PRIMITIVE_TOPOLOGY
	{
		PRIMITIVE_TOPOLOGY_UNDEFINED                    = 0,
		PRIMITIVE_TOPOLOGY_POINTLIST                    = 1,
		PRIMITIVE_TOPOLOGY_LINELIST                     = 2,
		PRIMITIVE_TOPOLOGY_LINESTRIP                    = 3,
		PRIMITIVE_TOPOLOGY_TRIANGLELIST                 = 4,
		PRIMITIVE_TOPOLOGY_TRIANGLESTRIP                = 5,
		PRIMITIVE_TOPOLOGY_LINELIST_ADJ                 = 10,
		PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ                = 11,
		PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ             = 12,
		PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ            = 13,
		PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST    = 33,
		PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST    = 34,
		PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST    = 35,
		PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST    = 36,
		PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST    = 37,
		PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST    = 38,
		PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST    = 39,
		PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST    = 40,
		PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST    = 41,
		PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST   = 42,
		PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST   = 43,
		PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST   = 44,
		PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST   = 45,
		PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST   = 46,
		PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST   = 47,
		PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST   = 48,
		PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST   = 49,
		PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST   = 50,
		PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST   = 51,
		PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST   = 52,
		PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST   = 53,
		PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST   = 54,
		PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST   = 55,
		PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST   = 56,
		PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST   = 57,
		PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST   = 58,
		PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST   = 59,
		PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST   = 60,
		PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST   = 61,
		PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST   = 62,
		PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST   = 63,
		PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST   = 64 
	};
	//defines options for texture sampling..copied from http://msdn.microsoft.com/en-us/library/ff476132(v=VS.85).aspx
	enum FILTER
	{
		FILTER_MIN_MAG_MIP_POINT                            = 0,
		FILTER_MIN_MAG_POINT_MIP_LINEAR                     = 0x1,
		FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT               = 0x4,
		FILTER_MIN_POINT_MAG_MIP_LINEAR                     = 0x5,
		FILTER_MIN_LINEAR_MAG_MIP_POINT                     = 0x10,
		FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR              = 0x11,
		FILTER_MIN_MAG_LINEAR_MIP_POINT                     = 0x14,
		FILTER_MIN_MAG_MIP_LINEAR                           = 0x15,
		FILTER_ANISOTROPIC                                  = 0x55,
		FILTER_COMPARISON_MIN_MAG_MIP_POINT                 = 0x80,
		FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR          = 0x81,
		FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT    = 0x84,
		FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR          = 0x85,
		FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT          = 0x90,
		FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR   = 0x91,
		FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT          = 0x94,
		FILTER_COMPARISON_MIN_MAG_MIP_LINEAR                = 0x95,
		FILTER_COMPARISON_ANISOTROPIC                       = 0xd5,
		FILTER_TEXT_1BIT                                    = 0x80000000 
	};
	//defines texture address mode...copied from http://msdn.microsoft.com/en-us/library/ff476256(v=VS.85).aspx
	enum TEXTURE_ADDRESS_MODE
	{
		TEXTURE_ADDRESS_MODE_WRAP          = 1,
		TEXTURE_ADDRESS_MODE_MIRROR        = 2,
		TEXTURE_ADDRESS_MODE_CLAMP         = 3,
		TEXTURE_ADDRESS_MODE_BORDER        = 4,
		TEXTURE_ADDRESS_MODE_MIRROR_ONCE   = 5 
	};
	//defines comparision function..copied from http://msdn.microsoft.com/en-us/library/ff476101(v=VS.85).aspx
	enum COMPARISON_FUNC
	{
		COMPARISON_FUNC_NEVER           = 1,
		COMPARISON_FUNC_LESS            = 2,
		COMPARISON_FUNC_EQUAL           = 3,
		COMPARISON_FUNC_LESS_EQUAL      = 4,
		COMPARISON_FUNC_GREATER         = 5,
		COMPARISON_FUNC_NOT_EQUAL       = 6,
		COMPARISON_FUNC_GREATER_EQUAL   = 7,
		COMPARISON_FUNC_ALWAYS          = 8
	};
	//clearing flag..copied from http://msdn.microsoft.com/en-us/library/ff476099(v=VS.85).aspx
	enum CLEAR_FLAG
	{
		CLEAR_FLAG_DEPTH     = 0x1L,
		CLEAR_FLAG_STENCIL   = 0x2L 
	};
	//culling mode..copied from http://msdn.microsoft.com/en-us/library/ff476108(v=VS.85).aspx
	enum CULL_MODE
	{
		CULL_MODE_NONE    = 1,
		CULL_MODE_FRONT   = 2,
		CULL_MODE_BACK    = 3 
	};
	//fill mode..copied from http://msdn.microsoft.com/en-us/library/ff476131(v=VS.85).aspx
	enum FILL_MODE 
	{
		FILL_MODE_WIREFRAME   = 2,
		FILL_MODE_SOLID       = 3 
	};
	//SRV dimension from http://msdn.microsoft.com/en-us/library/ff476258(v=VS.85).aspx
	enum SRV_DIMENSION 
	{
		SRV_DIMENSION_UNKNOWN            = 0,
		SRV_DIMENSION_BUFFER             = 1,
		SRV_DIMENSION_TEXTURE1D          = 2,
		SRV_DIMENSION_TEXTURE1DARRAY     = 3,
		SRV_DIMENSION_TEXTURE2D          = 4,
		SRV_DIMENSION_TEXTURE2DARRAY     = 5,
		SRV_DIMENSION_TEXTURE2DMS        = 6,
		SRV_DIMENSION_TEXTURE2DMSARRAY   = 7,
		SRV_DIMENSION_TEXTURE3D          = 8,
		SRV_DIMENSION_TEXTURECUBE        = 9,
		SRV_DIMENSION_TEXTURECUBEARRAY   = 10,
		SRV_DIMENSION_BUFFEREX           = 11 
	};
	//UAV dimension from http://msdn.microsoft.com/en-us/library/ff476257(v=VS.85).aspx
	enum UAV_DIMENSION 
	{
		UAV_DIMENSION_UNKNOWN          = 0,
		UAV_DIMENSION_BUFFER           = 1,
		UAV_DIMENSION_TEXTURE1D        = 2,
		UAV_DIMENSION_TEXTURE1DARRAY   = 3,
		UAV_DIMENSION_TEXTURE2D        = 4,
		UAV_DIMENSION_TEXTURE2DARRAY   = 5,
		UAV_DIMENSION_TEXTURE3D        = 8 
	};
	//type of mapping from http://msdn.microsoft.com/en-us/library/ff476181(v=VS.85).aspx
	enum MAP 
	{
		MAP_READ                 = 1,
		MAP_WRITE                = 2,
		MAP_READ_WRITE           = 3,
		MAP_WRITE_DISCARD        = 4,
		MAP_WRITE_NO_OVERWRITE   = 5 
	};
	//blending types from http://msdn.microsoft.com/en-us/library/ff476086(v=VS.85).aspx
	enum BLEND 
	{
		BLEND_ZERO               = 1,
		BLEND_ONE                = 2,
		BLEND_SRC_COLOR          = 3,
		BLEND_INV_SRC_COLOR      = 4,
		BLEND_SRC_ALPHA          = 5,
		BLEND_INV_SRC_ALPHA      = 6,
		BLEND_DEST_ALPHA         = 7,
		BLEND_INV_DEST_ALPHA     = 8,
		BLEND_DEST_COLOR         = 9,
		BLEND_INV_DEST_COLOR     = 10,
		BLEND_SRC_ALPHA_SAT      = 11,
		BLEND_BLEND_FACTOR       = 14,
		BLEND_INV_BLEND_FACTOR   = 15,
		BLEND_SRC1_COLOR         = 16,
		BLEND_INV_SRC1_COLOR     = 17,
		BLEND_SRC1_ALPHA         = 18,
		BLEND_INV_SRC1_ALPHA     = 19 
	};

	//blending operation from http://msdn.microsoft.com/en-us/library/ff476088(v=VS.85).aspx
	enum BLEND_OP 
	{
		BLEND_OP_ADD            = 1,
		BLEND_OP_SUBTRACT       = 2,
		BLEND_OP_REV_SUBTRACT   = 3,
		BLEND_OP_MIN            = 4,
		BLEND_OP_MAX            = 5 
	};


};

class graphicsBase
{
	protected:

		//with of the render context
		unsigned int width;
		unsigned int height;

	public:

		//box structure
		struct box
		{
			unsigned int left;
			unsigned int top;
			unsigned int front;
			unsigned int right;
			unsigned int bottom;
			unsigned int back;
		};

		//buffer description
		struct bufferDesc
		{
			unsigned int byteWidth;
			graphicsDefinitions::USAGE usage;
			unsigned int bindFlags;
			unsigned int cpuAccessFlags;
			unsigned int miscFlags;
			unsigned int structureByteStride;
		};

		//texture 1D description
		struct texture1DDesc
		{
			unsigned int width;
			unsigned int mipLevels;
			unsigned int arraySize;
			graphicsDefinitions::DATA_FORMAT format;
			graphicsDefinitions::USAGE usage;
			unsigned int bindFlags;
			unsigned int cpuAccessFlags;
			unsigned int miscFlags;
		};

		//multi sampling description
		struct sampleDesc
		{
			unsigned int count;
			unsigned int quality;
		};

		//texture 2D description
		struct texture2DDesc
		{
			unsigned int width;
			unsigned int height;
			unsigned int mipLevels;
			unsigned int arraySize;
			graphicsDefinitions::DATA_FORMAT format;
			sampleDesc sampleDesc;
			graphicsDefinitions::USAGE usage;
			unsigned int bindFlags;
			unsigned int cpuAccessFlags;
			unsigned int miscFlags;
		};

		//texture 3D description
		struct texture3DDesc
		{
			unsigned int width;
			unsigned int height;
			unsigned int depth;
			unsigned int mipLevels;
			graphicsDefinitions::DATA_FORMAT format;
			graphicsDefinitions::USAGE usage;
			unsigned int bindFlags;
			unsigned int cpuAccessFlags;
			unsigned int miscFlags;
		};

		//render targets blend description
		struct renderTargetBlendDesc 
		{
			bool blendEnable;
			graphicsDefinitions::BLEND srcBlend;
			graphicsDefinitions::BLEND destBlend;
			graphicsDefinitions::BLEND_OP blendOp;
			graphicsDefinitions::BLEND srcBlendAlpha;
			graphicsDefinitions::BLEND destBlendAlpha;
			graphicsDefinitions::BLEND_OP blendOpAlpha;
			unsigned char renderTargetWriteMask;
		};

		//blend description
		struct blendDesc
		{
			bool alphaToCoverageEnable;
			bool independentBlendEnable;
			renderTargetBlendDesc renderTarget[8]; //can have upto 8 render targets
		};


		//class to handle all gpu resources textures, depth, stencil, 
		class resourceBase
		{
			public:
				//constructor
				resourceBase(void){};

				//returns the type
				virtual graphicsDefinitions::RESOURCE_DIMENSION getType(void)=0;
				
				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~resourceBase(){};
		};

		//class to handle buffer
		class bufferBase:public resourceBase
		{
			public:
				//constructor
				bufferBase(void){};

				//returns the type
				virtual graphicsDefinitions::RESOURCE_DIMENSION getType(void)=0;

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~bufferBase(){};
		};

		//class to handle 1D texture
		class texture1DBase:public resourceBase
		{
			public:
				//constructor
				texture1DBase(void){};

				//returns the type
				virtual graphicsDefinitions::RESOURCE_DIMENSION getType(void)=0;

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~texture1DBase(){};
		};

		//class to handle 2D texture
		class texture2DBase:public resourceBase
		{
			public:
				//constructor
				texture2DBase(void){};

				//returns the type
				virtual graphicsDefinitions::RESOURCE_DIMENSION getType(void)=0;

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~texture2DBase(){};
		};

		//class to handle 3D texture
		class texture3DBase:public resourceBase
		{
			public:
				//constructor
				texture3DBase(void){};

				//returns the type
				virtual graphicsDefinitions::RESOURCE_DIMENSION getType(void)=0;

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~texture3DBase(){};
		};
				
		//class to handle raw shader data
		class blobBase
		{
			public:
				//constructor
				blobBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~blobBase(){};
		};

		//class to handle input layout for vertex
		class inputLayoutBase
		{
			public:
				//constructor
				inputLayoutBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~inputLayoutBase(){};
		};

		//class to handle vertex shader data
		class shaderVertexBase
		{
			public:
				//constructor
				shaderVertexBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~shaderVertexBase(){};
		};

		//class to handle hull shader data
		class shaderHullBase
		{
			public:
				//constructor
				shaderHullBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~shaderHullBase(){};
		};

		//class to handle domain shader data
		class shaderDomainBase
		{
			public:
				//constructor
				shaderDomainBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~shaderDomainBase(){};
		};

		//class to handle geometry shader data
		class shaderGeometryBase
		{
			public:
				//constructor
				shaderGeometryBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~shaderGeometryBase(){};
		};

		//class to handle pixel shader data
		class shaderPixelBase
		{
			public:
				//constructor
				shaderPixelBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~shaderPixelBase(){};
		};

		//class to handle compute shader data
		class shaderComputeBase
		{
			public:
				//constructor
				shaderComputeBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~shaderComputeBase(){};
		};
				
		//description of input element similar to http://msdn.microsoft.com/en-us/library/bb205316(VS.85).aspx
		struct inputElementDesc
		{
			graphicsDefinitions::INPUT_DATA_TYPE type; //type of data
			unsigned int index; //index to put texture0,texute1
			graphicsDefinitions::DATA_FORMAT format; //data's internal format
			unsigned int inputSlot;	//slon no
			unsigned int alignedByteOffset; //starting offset
			graphicsDefinitions::INPUT_CLASSIFICATION inputSlotClass; //class on input slot
			unsigned int instanceDataStepRate; //instance to draw before stepping one unit
		};


		//render target view
		class renderTargetViewBase
		{
			public:
				//constructor
				renderTargetViewBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~renderTargetViewBase(){};
		};

		//depth stencil view
		class depthStencilViewBase
		{
			public:
				//constructor
				depthStencilViewBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~depthStencilViewBase(){};
		};

		//shader resource view
		class shaderResourceViewBase
		{
			public:
				//constructor
				shaderResourceViewBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~shaderResourceViewBase(){};
		};

		//Unordered Access View
		class unorderedAccessViewBase
		{
			public:
				//constructor
				unorderedAccessViewBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~unorderedAccessViewBase(){};
		};
		

		//sampler state
		class samplerStateBase
		{
			public:
				//constructor
				samplerStateBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~samplerStateBase(){};
		};

		//class instance for shader
		class classInstanceBase
		{
			public:
				//constructor
				classInstanceBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~classInstanceBase(){};
		};

		//class for Rasterizer State
		class rasterizerStateBase
		{
			public:
				//constructor
				rasterizerStateBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~rasterizerStateBase(){};
		};

		//command list
		class commandListBase
		{
			public:
				//constructor
				commandListBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~commandListBase(){};
		};

		//blend state
		class blendStateBase
		{
			public:
				//constructor
				blendStateBase(void){};

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~blendStateBase(){};
		};

		
		//class for immediate context
		class deviceContextBase
		{
			protected:

			public:
				//constructor
				deviceContextBase(void)
				{};

				//resizes the output screen
				virtual bool resize(const unsigned int &_width,const unsigned int &_height)=0;

				//Restore all default settings of the device context
				virtual void clearState(void)=0;

				//create a command list and record command
				virtual bool finishCommandList(bool restoreDeferredContextState, commandListBase* clData)=0;
				//queues command from command list to the device
				virtual void executeCommandList(commandListBase* clData, bool restoreContextState)=0;
				
				//sets input layout
				virtual void setInputLayout(inputLayoutBase *inLayData)=0;
				
				//updates sub resource
				virtual void updateSubResource(resourceBase *destinationBuffer, unsigned int destinationSubresource, const box *destinationBox, const void *sourceData, unsigned int sourceRowPitch, unsigned int sourceDepthPitch)=0;
				//copies one buffer to another
				virtual void copyResource(resourceBase *dest, resourceBase *src)=0;
				//maps the data
				virtual void *map(resourceBase *bData, unsigned int subresource, graphicsDefinitions::MAP mapType,unsigned int &rowPitch, unsigned int &depthPitch)=0;
				//unmap the data
				virtual void unmap(resourceBase *bData, unsigned int subresource)=0;

				//sets vertex buffer
				virtual void setVertexBuffers(unsigned int startSlot,unsigned int bufferCount, bufferBase *bufferDatas,unsigned int strides,unsigned int offsets)=0;
				//sets index buffer
				virtual void setIndexBuffer(bufferBase *bufferData,graphicsDefinitions::DATA_FORMAT format, unsigned int offset)=0;
				

				//sets primitive topology
				virtual void setPrimitiveTopology(graphicsDefinitions::PRIMITIVE_TOPOLOGY topology)=0;

				//Draw non-indexed, non-instanced primitives
				virtual void draw(unsigned int vertexCount,unsigned int startVertexLocation)=0;
				//draw indexed primitive
				virtual void drawIndexed(unsigned int indexCount,unsigned int startIndexLocation,int baseVertexLocation)=0;
				//Draw non-indexed, instanced primitives.
				virtual void drawInstanced(unsigned int vertexCountPerInstance,unsigned int instanceCount,unsigned int startVertexLocation,unsigned int startInstanceLocation)=0;
				//Draw indexed, instanced primitives.
				virtual void drawIndexedInstanced(unsigned int indexCountPerInstance,unsigned int instanceCount,unsigned int startIndexLocation,int baseVertexLocation,unsigned int startInstanceLocation)=0;
				//Draw instanced, GPU-generated primitives.
				virtual void drawInstancedIndirect(bufferBase *pBufferForArgs,unsigned int alignedByteOffsetForArgs)=0;
				//Draw indexed, instanced, GPU-generated primitives.
				virtual void drawIndexedInstancedIndirect(bufferBase *pBufferForArgs,unsigned int alignedByteOffsetForArgs)=0;

				//clear the render target
				virtual void clearRenderTargetView(renderTargetViewBase *rTargetView, float *clearColor)=0;

				//Clears the depth-stencil resource
				virtual void clearDepthStencilView(depthStencilViewBase *dStencilView,unsigned int clearFlags, float depth, unsigned int stencil)=0;

				//set constant buffer in vertex shader
				virtual void VSSetConstantBuffers(unsigned int startSlot,unsigned int numBuffers, bufferBase *constantBuffers, unsigned int uniformIndex)=0;
				//set constant buffer in hull shader
				virtual void HSSetConstantBuffers(unsigned int startSlot,unsigned int numBuffers, bufferBase *constantBuffers, unsigned int uniformIndex)=0;
				//set constant buffer in domain shader
				virtual void DSSetConstantBuffers(unsigned int startSlot,unsigned int numBuffers, bufferBase *constantBuffers, unsigned int uniformIndex)=0;
				//set constant buffer in geometry shader
				virtual void GSSetConstantBuffers(unsigned int startSlot,unsigned int numBuffers, bufferBase *constantBuffers, unsigned int uniformIndex)=0;
				//set constant buffer in pixel shader
				virtual void PSSetConstantBuffers(unsigned int startSlot,unsigned int numBuffers, bufferBase *constantBuffers, unsigned int uniformIndex)=0;
				//set constant buffer in compute shader
				virtual void CSSetConstantBuffers(unsigned int startSlot,unsigned int numBuffers, bufferBase *constantBuffers, unsigned int uniformIndex)=0;

				//set shader resources in vertex shader
				virtual void VSSetShaderResources(unsigned int startSlot,unsigned int numViews, shaderResourceViewBase *shaderResources, unsigned int uniformIndex)=0;
				//set shader resources in hull shader
				virtual void HSSetShaderResources(unsigned int startSlot,unsigned int numViews, shaderResourceViewBase *shaderResources, unsigned int uniformIndex)=0;
				//set shader resources in domain shader
				virtual void DSSetShaderResources(unsigned int startSlot,unsigned int numViews, shaderResourceViewBase *shaderResources, unsigned int uniformIndex)=0;
				//set shader resources in geometry shader
				virtual void GSSetShaderResources(unsigned int startSlot,unsigned int numViews, shaderResourceViewBase *shaderResources, unsigned int uniformIndex)=0;
				//set shader resources in pixel shader
				virtual void PSSetShaderResources(unsigned int startSlot,unsigned int numViews, shaderResourceViewBase *shaderResources, unsigned int uniformIndex)=0;
				//set shader resources in compute shader
				virtual void CSSetShaderResources(unsigned int startSlot,unsigned int numViews, shaderResourceViewBase *shaderResources, unsigned int uniformIndex)=0;
				//set unordered access view in compute shader
				virtual void CSSetUnorderedAccessViews(unsigned int startSlot,unsigned int numUAVs, unorderedAccessViewBase *uavResources,unsigned int *initialCounts)=0;

				//set sampler in vertex shader
				virtual void VSSetSamplers(unsigned int startSlot,unsigned int numSamplers, samplerStateBase *samplers)=0;
				//set sampler in hull shader
				virtual void HSSetSamplers(unsigned int startSlot,unsigned int numSamplers, samplerStateBase *samplers)=0;
				//set sampler in domain shader
				virtual void DSSetSamplers(unsigned int startSlot,unsigned int numSamplers, samplerStateBase *samplers)=0;
				//set sampler in geometry shader
				virtual void GSSetSamplers(unsigned int startSlot,unsigned int numSamplers, samplerStateBase *samplers)=0;
				//set sampler in pixel shader
				virtual void PSSetSamplers(unsigned int startSlot,unsigned int numSamplers, samplerStateBase *samplers)=0;
				//set sampler in compute shader
				virtual void CSSetSamplers(unsigned int startSlot,unsigned int numSamplers, samplerStateBase *samplers)=0;


				//set vertex shader
				virtual void VSSetShader(shaderVertexBase *shader, classInstanceBase *classInstances,unsigned int numClassInstances)=0;
				//set hull shader
				virtual void HSSetShader(shaderHullBase *shader, classInstanceBase *classInstances,unsigned int numClassInstances)=0;
				//set domain shader
				virtual void DSSetShader(shaderDomainBase *shader, classInstanceBase *classInstances,unsigned int numClassInstances)=0;
				//set geometry shader
				virtual void GSSetShader(shaderGeometryBase *shader, classInstanceBase *classInstances,unsigned int numClassInstances)=0;
				//set pixel shader
				virtual void PSSetShader(shaderPixelBase *shader, classInstanceBase *classInstances,unsigned int numClassInstances)=0;
				//set compute shader
				virtual void CSSetShader(shaderComputeBase *shader, classInstanceBase *classInstances,unsigned int numClassInstances)=0;
				//called after all the shaders are set before drawing (for opengl shader object) compatibility
				virtual void shaderBegin(void)=0;
				//called after all the drawing is done
				virtual void shaderEnd(void)=0;
				//returns uniform block index. only used in opengl
				virtual unsigned int getUniformBlockIndex(char *name)=NULL;
				//returns uniform location. only used in opengl
				virtual unsigned int getUniformLocation(char *name)=NULL;

		
				//sets rasterizer state
				virtual void RSSetState(rasterizerStateBase *rsData)=0;

				//execute direct compute command list from a thread group
				virtual void dispatch(unsigned int threadGroupCountX, unsigned int threadGroupCountY, unsigned int threadGroupCountZ)=0;


				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~deviceContextBase(){};
		};

		//class for device
		class deviceBase
		{
			public:
				//constructor
				deviceBase(void){};

				//create deferred context
				virtual bool createDeferredContext(deviceContextBase* dcData)=0;
				
				//creates vertex shader
				virtual bool createVertexShader(blobBase* shRawData,shaderVertexBase* shData)=0;
				//creates hull shader
				virtual bool createHullShader(blobBase* shRawData,shaderHullBase* shData)=0;
				//creates domain shader
				virtual bool createDomainShader(blobBase* shRawData,shaderDomainBase* shData)=0;
				//creates geometry shader
				virtual bool createGeometryShader(blobBase* shRawData,shaderGeometryBase* shData)=0;
				//creates pixel shader
				virtual bool createPixelShader(blobBase* shRawData,shaderPixelBase* shData)=0;
				//creates compute shader
				virtual bool createComputeShader(blobBase* shRawData,shaderComputeBase* shData)=0;

				//creates input layout
				virtual bool createInputLayout(inputElementDesc *inputDesc, unsigned int inputDescCount,blobBase *shData,inputLayoutBase *inLayData)=0;
				//creates buffer in gpu
				virtual bool createBuffer(bufferDesc desc, void *pSysMem, unsigned int sysMemPitch, unsigned int sysMemSlicePitch, bufferBase *bData)=0;	
				//creates 1D texture
				virtual bool createTexture1D(texture1DDesc desc, void *pSysMem, unsigned int sysMemPitch, unsigned int sysMemSlicePitch, texture1DBase *tData)=0;
				//creates 2D texture
				virtual bool createTexture2D(texture2DDesc desc, void *pSysMem, unsigned int sysMemPitch, unsigned int sysMemSlicePitch, texture2DBase *tData)=0;
				//creates 3D texture
				virtual bool createTexture3D(texture3DDesc desc, void *pSysMem, unsigned int sysMemPitch, unsigned int sysMemSlicePitch, texture3DBase *tData)=0;
					
				
				//creates shader resource view from file
				virtual bool createShaderResourceViewFromFile(char* fileName, shaderResourceViewBase * srvData)=0;
				//creates shader resource view. param0, param1, param2, param3 depends on the dimension type. Please refer to dx version for params
				virtual bool createShaderResourceView(resourceBase *bData, graphicsDefinitions::DATA_FORMAT format, graphicsDefinitions::SRV_DIMENSION dimension, unsigned int param0, unsigned int param1, unsigned int param2, unsigned int param3,shaderResourceViewBase* srvData)=0;
				//creates unordered access view. param0, param1, param2 depends on the dimension type. Please refer to dx version for params
				virtual bool createUnorderedAccessView(resourceBase *bData, graphicsDefinitions::DATA_FORMAT format, graphicsDefinitions::UAV_DIMENSION dimension, unsigned int param0, unsigned int param1, unsigned int param2, unorderedAccessViewBase* uavData)=0;

				//creates sampler state
				virtual bool createSamplerState(graphicsDefinitions::FILTER filter,	graphicsDefinitions::TEXTURE_ADDRESS_MODE addMode[3], float mipLODBias, unsigned int maxAnisotropy, graphicsDefinitions::COMPARISON_FUNC comparisonFunc, float borderColor[4], float minLOD, float maxLOD, samplerStateBase *ssBase)=0;

				//creates rasterizer state
				virtual bool createRasterizerState(graphicsDefinitions::FILL_MODE fillMode,graphicsDefinitions::CULL_MODE cullMode,bool frontCounterClockwise,int depthBias,float depthBiasClamp,float slopeScaledDepthBias,bool depthClipEnable, bool scissorEnable, bool multisampleEnable, bool antialiasedLineEnable,	rasterizerStateBase *rsData)=0;
		
				//creates a blend state
				virtual bool createBlendState(const blendDesc *bStateDesc,blendStateBase *bStateData)=0;

				//clears the buffer
				virtual void clear(void)=0;

				//destructor
				virtual ~deviceBase(){};
		};
				
		//constructor
		graphicsBase(void)
		{
			width=800;
			height=600;
		};

		//constructor
		graphicsBase(unsigned int _width,unsigned int _height):width(_width),height(_height)
		{
		};
		
		//initilizes the device
		virtual bool init(deviceBase *gDevice, deviceContextBase *dContext, texture2DBase *renderTarget, texture2DBase *depthStencil,renderTargetViewBase *rTargetView,depthStencilViewBase *dStencilView)=0;

		//closes the device
		virtual bool close(void)=0;

		//resizes the output screen
		virtual bool resize(deviceBase *gDevice, deviceContextBase *dContext, texture2DBase *renderTarget, texture2DBase *depthStencil,renderTargetViewBase *rTargetView,depthStencilViewBase *dStencilView, const unsigned int &_width,const unsigned int &_height)=0;

		//swaps back and front buffer
		virtual void swapBuffer(void)=0;

		//sets vsync option
		virtual void setVerticalSync(bool option)=0;

		//checks for any error
		virtual bool checkError(void)=0;

		//destructor
		virtual ~graphicsBase(){};

		//compiles shader for the file
		virtual bool compileShaderFromFile(char* fileName,char *entryPoint, char *shaderModel, blobBase* shData)=0;

		//returns width of camera in screen space
		const unsigned int &getWidth(void) const {return width;}

		//returns height of camera in screen space
		const unsigned int &getHeight(void) const {return height;}

};


#endif